package com.idanchuang.component.webflux.util;

import com.zoi7.component.core.base.BaseClass;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequest;

import java.net.InetSocketAddress;

/**
 * 获取请求客户端真实ip地址
 */
public class IpUtils extends BaseClass {

    private static final String[] NAMES = {
            "http_x_forwarded_for",
            "x-forwarded-for",
            "X-Original-Forwarded-For",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_CLIENT_IP",
            "X-Real-IP"
    };

    /**
     * 获取客户端ip
     * @param request 请求
     * @return 客户端ip
     */
    public static String getClientIp(HttpRequest request) {
        HttpHeaders headers = request.getHeaders();
        for (String name : NAMES) {
            String ip = getAndResolveIp(headers, name);
            if (notBlank(ip)) {
                return ip;
            }
        }
        if (request instanceof ServerHttpRequest) {
            InetSocketAddress address = ((ServerHttpRequest)request).getRemoteAddress();
            if (address != null) {
                String ip = address.getAddress().getHostAddress();
                if (notBlank(ip)) {
                    return ip;
                }
            }
        } else if (request instanceof org.springframework.http.server.ServerHttpRequest) {
            InetSocketAddress address = ((org.springframework.http.server.ServerHttpRequest)request).getRemoteAddress();
            String ip = address.getAddress().getHostAddress();
            if (notBlank(ip)) {
                return ip;
            }
        }
        return null;
    }

    private static String getAndResolveIp(HttpHeaders headers, String headerName) {
        String ip = headers.getFirst(headerName);
        return resolveIp(ip);
    }

    private static String resolveIp(String ips) {
        String ip = null;
        if (isBlank(ips)) {
            return null;
        }
        if (ips.contains(",")) {
            ip = ips.split(",")[0].trim();
        }
        return ip;
    }

}
